﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel;
using Excel = Microsoft.Office.Interop.Excel;
using System.Threading;
using System.ComponentModel;

namespace StuMana.Services
{
    class ExcelInterface
    {

        private System.ComponentModel.BackgroundWorker backgroundWorker1;
        string column ;
        int row ;
        ExcelBase excel = new ExcelBase();
        //creates the main header 
        ExcelBE be = null;
        int height; 
        int width;
        List<string>[] _list;
        string[] _columnName;
        int _pos;
        int _type;
        int _pos2;
        int _type2;

        public ExcelInterface(){}
        /// <summary>
        /// 
        /// </summary>
        /// <param name="list"></param>
        /// <param name="columnName"></param>
        /// <param name="pos"> position of time 1</param>
        /// <param name="type"></param>
        /// <param name="pos2"> position of time 2</param>
        /// <param name="type2"> 1: longtime
        ///                      2: shortime </param>
        public ExcelInterface(List<string>[] list,string[] columnName,int pos=-1, int type=-1,int pos2=-1,int type2=-2)
        {
            height = list[0].Count;
            width = list.Length;
            column = "B";
            row = 2;
            _list=list;
            _columnName = columnName;
            _pos=pos;
            _type=type;
            _pos2=pos2;
            _type2=type2;

            backgroundWorker1  = new System.ComponentModel.BackgroundWorker();
            backgroundWorker1.DoWork+=new DoWorkEventHandler(backgroundWorker1_DoWork);
            backgroundWorker1.ProgressChanged+=new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
            backgroundWorker1.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
            backgroundWorker1.WorkerReportsProgress = true;

            if (excel.getlocation() != null)
            {
                if (backgroundWorker1.IsBusy != true)
                {
                    // create a new instance of the alert form
                    alert = new UI.AlertForm();
                    // event handler for the Cancel button in AlertForm
                    alert.Canceled += new EventHandler<EventArgs>(buttonCancel_Click);
                    alert.Show();
                    // Start the asynchronous operation.
                    backgroundWorker1.RunWorkerAsync();
                }
            }
        }

        // return the string - determine datetime string or normal string
        private string getstring(int i, int j, List<string>[] list, int pos, int type, int pos2, int type2)
        {            
            if (j == pos)
            {
                DateTime dt = Convert.ToDateTime(list[j][i]);
                if(type ==1)                
                    return dt.ToString("MM/dd/yyyy hh:mm:ss tt");
                else
                    return dt.ToString("MM/dd/yyyy");

            }
            else if (j == pos2)
            {
                DateTime dt = Convert.ToDateTime(list[j][i]);
                if (type2 == 1)
                    return dt.ToString("MM/dd/yyyy hh:mm:ss tt");
                else
                    return dt.ToString("MM/dd/yyyy");

            }
            else
            {
                return list[j][i];
            }
        }
        // return cell format
        private string cellFormat(int j, int pos, int type, int pos2, int type2)
        {
            if (j == pos)
            {
                if(type==1)
                    return "MM/dd/yyyy hh:mm:ss AM/PM";
                else
                    return "MM/dd/yyyy";
            }
            else if (j == pos2)
            {
                if (type2 == 1)
                    return "MM/dd/yyyy hh:mm:ss AM/PM";
                else
                    return "MM/dd/yyyy";
            }
            else
                return null;
        }
        // increment string for corrent excel column
        static string Increment(string s)
        {

            // first case - string is empty: return "A"

            if ((s == null) || (s.Length == 0))
                return "A";

            // next case - last char is less than 'Z': simply increment last char

            char lastChar = s[s.Length - 1];

            string fragment = s.Substring(0, s.Length - 1);

            if (lastChar < 'Z')
            {
                ++lastChar;
                return fragment + lastChar;

            }

            // next case - last char is 'z': roll over and increment preceding string

            return Increment(fragment) + 'A';

        }


        #region SaveProgress

        UI.AlertForm alert;

        // This event handler cancels the backgroundworker, fired from Cancel button in AlertForm.
        private void buttonCancel_Click(object sender, EventArgs e)
        {
            if (backgroundWorker1.WorkerSupportsCancellation == true)
            {
                // Cancel the asynchronous operation.
                backgroundWorker1.CancelAsync();
                // Close the AlertForm
                alert.Close();
            }
        }

        // This event handler is where the time-consuming work is done.
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            int percent;
            // choose saved location
            if (height > 0)
            {

                // create the first row
                for (int j = 0; j < width; j++)
                {
                    be = new ExcelBE(
                            2, j + 2,
                            _columnName[j],
                            column + row.ToString(),
                            column + row.ToString(),
                            "YELLOW",
                            false,
                            _columnName[j].Length + 2,
                            null,
                            null);
                    excel.InsertData(be);
                    column = Increment(column);
                }
                column = "B";
                row++;

                // copy data
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        be = new ExcelBE(
                            i + 3, j + 2,
                            getstring(i, j, _list, _pos, _type, _pos2, _type2),
                            column + row.ToString(),
                            column + row.ToString(),
                            null,
                            false,
                            _list[j][i].Length + 2,
                            null,
                            cellFormat(j, _pos, _type, _pos2, _type2));
                        excel.InsertData(be);
                        column = Increment(column);
                    }
                    column = "B";
                    row++;
                    percent = ((i+1) * 100) / height;
                    if (worker.CancellationPending == true)
                    {
                        e.Cancel = true;
                        break;
                    }
                    else 
                    {
                        // Perform a time consuming operation and report progress.
                        worker.ReportProgress(percent);
                       // System.Threading.Thread.Sleep(500);
                    }
                }

                // save file
                excel.savefile();
                excel = null;
            }
        }

        // This event handler updates the progress.
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Show the progress in main form (GUI)
            //  labelResult.Text = (e.ProgressPercentage.ToString() + "%");
            // Pass the progress to AlertForm label and progressbar
            alert.Message = "In progress, please wait... " + e.ProgressPercentage.ToString() + "%";
            alert.ProgressValue = e.ProgressPercentage;
        }

        // This event handler deals with the results of the background operation.
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {
                MessageBox.Show("Cancel saving !","Alert");
            }
            else if (e.Error != null)
            {
                MessageBox.Show("Error: " + e.Error.Message,"Error");
            }
            else
            {
                MessageBox.Show("Done!","Alert");
            }
            // Close the AlertForm
            alert.Close();
        }
        #endregion
    }    
}
